<template>
  <a-collapse :default-active-key="[activeKey]" accordion>
    <a-collapse-item key="base" header="常规">
      <base-info :business-object="elementBusinessObject" :id-edit-disabled="idEditDisabled" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item v-if="elementType == 'Process'" key="message" header="消息与信号">
      <message-info />
    </a-collapse-item>
    <a-collapse-item v-if="conditionFormVisible" key="condition" header="流程条件">
      <flow-condition-info :business-object="elementBusinessObject" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item v-if="formVisible" key="form" header="表单">
      <form-info :id="elementId" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item v-if="elementType.indexOf('Task') !== -1" key="task" header="任务">
      <task-info :id="elementId" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item v-if="elementType.indexOf('Task') !== -1 && elementType !== 'UserTask'" key="multiInstance" header="多实例">
      <multi-instance-info :business-object="elementBusinessObject" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item key="listeners" header="执行监听器">
      <listener-info :id="elementId" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item v-if="elementType == 'UserTask'" key="taskListeners" header="任务监听器">
      <task-listener-info :id="elementId" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item key="extensions" header="扩展属性">
      <extension-info :id="elementId" :type="elementType" />
    </a-collapse-item>
    <a-collapse-item key="other" header="其他">
      <other-info :id="elementId" />
    </a-collapse-item>
  </a-collapse>
</template>
<script lang="ts" setup>
import { propTypes } from "@/utils/propTypes";

const activeKey = ref("base");
const props = defineProps({
  bpmnModeler: propTypes.object.def(undefined),
  idEditDisabled: propTypes.bool.def(false)
});

const elementId = ref("");
const elementType = ref("");
const elementBusinessObject = ref({});
const formVisible = ref(false);
const conditionFormVisible = ref(false);
const timer = ref<any>(undefined);
/**
 * 初始化modeler
 */
const initModels = () => {
  if (!props.bpmnModeler?.value) {
    timer.value = setTimeout(() => {
      initModels();
    }, 10);
    return;
  }
  if (timer.value) {
    clearTimeout(timer.value);
  }
  window.bpmnInstances = {
    modeler: props.bpmnModeler.value,
    modeling: props.bpmnModeler.value.get("modeling"),
    moddle: props.bpmnModeler.value.get("moddle"),
    eventBus: props.bpmnModeler.value.get("eventBus"),
    bpmnFactory: props.bpmnModeler.value.get("bpmnFactory"),
    elementFactory: props.bpmnModeler.value.get("elementFactory"),
    elementRegistry: props.bpmnModeler.value.get("elementRegistry"),
    replace: props.bpmnModeler.value.get("replace"),
    selection: props.bpmnModeler.value.get("selection")
  };
  getActiveElement();
};
const getActiveElement = () => {
  initFormOnChanged(null);
  props.bpmnModeler?.on("import.done", (e: any) => {
    initFormOnChanged(null);
  });
  // 监听选择事件
  props.bpmnModeler?.on("selection.changed", ({ newSelection }: { newSelection: any[] }) => {
    initFormOnChanged(newSelection[0] || null);
  });
  props.bpmnModeler?.on("element.changed", ({ element }: { element: { id: string } }) => {
    if (element && element.id === elementId.value) {
      initFormOnChanged(element);
    }
  });
};

const initFormOnChanged = (element: any) => {
  let activatedElement = element;
  if (!activatedElement) {
    activatedElement =
      window.bpmnInstances.elementRegistry.find((el: any) => el.type === "bpmn:Process") ??
      window.bpmnInstances.elementRegistry.find((el: any) => el.type === "bpmn:Collaboration");
  }
  if (!activatedElement) {
    return;
  }
  window.bpmnInstances.bpmnElement = activatedElement;
  elementId.value = activatedElement.id;
  elementType.value = activatedElement.type.split(":")[1] || "";
  elementBusinessObject.value = JSON.parse(JSON.stringify(activatedElement.businessObject));
  conditionFormVisible.value =
    elementType.value == "SequenceFlow" && activatedElement.source && activatedElement.source.type.indexOf("StartEvent") == -1;
  formVisible.value = elementType.value === "UserTask" || elementType.value === "StartEvent";
};

onMounted(() => {
  nextTick(() => {
    initModels();
  });
});
onBeforeUnmount(() => {
  window.bpmnInstances = null; // 现在不应该报错
});
</script>
<style lang="less" scoped>
:deep(.arco-collapse-item-content) {
  padding-left: 15px;
  background-color: var(--color-bg-1);
}
</style>
